package com.yuwenchao.superafflatus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yuwenchao.superafflatus.mapper.SuperLoginRoleMenuMapper;
import com.yuwenchao.superafflatus.mapper.SuperLoginRoleUserMapper;
import com.yuwenchao.superafflatus.mapper.SuperLoginUserMapper;
import com.yuwenchao.superafflatus.pojo.entity.SuperLoginMenu;
import com.yuwenchao.superafflatus.pojo.entity.SuperLoginRole;
import com.yuwenchao.superafflatus.pojo.entity.SuperLoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author chaooGG
 * @version 1.0
 * @date 2021/7/23 11:02
 */
@Slf4j
@Service
public class LoginUserDetailsService implements UserDetailsService {

    @Autowired
    SuperLoginUserMapper loginUserMapper;


    @Autowired
    SuperLoginRoleUserMapper roleUserMapper;


    @Autowired
    SuperLoginRoleMenuMapper roleMenuMapper;

    @Autowired
    private BCryptPasswordEncoder encoding;



    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //调用usersMapper方法，根据用户名查询数据库
        QueryWrapper<SuperLoginUser> wrapper = new QueryWrapper();
        wrapper.eq("username", username);
        SuperLoginUser loginUser = loginUserMapper.selectOne(wrapper);

        //判断
        if (loginUser == null) {//数据库没有用户名，认证失败
            log.info("用户名不存在！");
            //   throw  new UsernameNotFoundException("用户名不存在！");
            throw new BadCredentialsException("帐号不存在，请重新输入！");
        }


        List<SuperLoginRole> loginRolesList = roleUserMapper.selectRoleByUserId(loginUser.getId());
        List<SuperLoginMenu> loginMenusList = roleMenuMapper.selectMenuByUserId(loginUser.getId());
        List<GrantedAuthority> auths = new ArrayList<>();

        //处理角色
        for (SuperLoginRole role : loginRolesList) {
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + role.getName());
            auths.add(authority);
        }
        //处理菜单
        for (SuperLoginMenu menu : loginMenusList) {
            auths.add(new SimpleGrantedAuthority(menu.getPermission()));

        }

        //获取当前请求
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String pageusername = req.getParameter("username");
        String pagepassword = req.getParameter("password");
        String code = req.getParameter("verifyCode");//从当前请求中拿到code参数
        //String ipAddr = IpUtils.getIpAddr(req);
        String verifyCode = (String) req.getSession().getAttribute("verifyCode");//从session中获取生成的验证码字符串

        //这里做判断是为了防止 记住我 功能失效   这里存在安全隐患     判断页面和验证码两个都为空 记住我功能直接返回
        if ((pagepassword == null) && (code == null)) {
            return new User(loginUser.getUsername(),
                    encoding.encode(loginUser.getPassword()), auths);

        } else {  //常规逻辑验证
            /*if (!pagepassword.equals(loginUser.getPassword())) {
                throw new BadCredentialsException("密码错误，请重新输入！");
            }*/
            if (encoding.matches(pagepassword,loginUser.getPassword())==false) {
                throw new BadCredentialsException("密码错误，请重新输入！");
            }
           // boolean matches = encoding.matches("123456",encode);
            //验证码非空判断
            if (StringUtils.isBlank(code)) {
                throw new BadCredentialsException("验证码不能为空！");
            }
            //比较验证码是否相同
            if (StringUtils.isBlank(code) || StringUtils.isBlank(verifyCode) || !Objects.equals(code, verifyCode)) {
                log.info("验证码错误!");
                //  throw new AuthenticationServiceException("验证码错误!");
                throw new BadCredentialsException("验证码错误，请重新输入！");

            }

            return new User(loginUser.getUsername(),
                    loginUser.getPassword(), auths);
        }
    }
}
